from time import clock
from bond import Bond
from loa_game import WHITE, BLACK, LinesOfActionState
from modified_alpha_beta import ModifiedAlphaBetaSearch
from utilities.noFramePenaltyAlphaBeta import BondNoFramePenalty,\
    ModifiedAlphaBetaSearchNoPenalty

class GameRunner():
    '''
    Runs a game.
    '''
    
    def __init__(self, initial_state, agents, turn_time_limit, setup_time_limit):
        '''
        Constructor.
        
        @param initial_state: The initial game state.
        @param agents: A dictionary that maps players to their agents.
        @param turn_time_limit: The time limit of each turn.
        @param setup_time_limit: The time limit for setting up the agent.
        '''
        self.initial_state = initial_state
        self.agents = agents
        self.turn_time_limit = turn_time_limit
        self.setup_time_limit = setup_time_limit
    
    def run(self):
        '''
        Runs the game. Prints actions and states.
        
        @return: The game's winner.
        '''
        for player, agent in self.agents.items():
            start = clock()
            agent.setup(player, self.initial_state, self.turn_time_limit, self.setup_time_limit)
            setup_time = clock() - start
#            if setup_time > self.setup_time_limit:
#                raise Exception(str(player) + ' failed to set up in time.')
        
        state = self.initial_state
        while state.getWinner() is None:
            agent = self.agents[state.getCurrentPlayer()]
            start = clock()
            action = agent.move(state)
#            turn_time = clock() - start
#            print "Turn Time was: ", turn_time
#            if turn_time > self.turn_time_limit and isinstance(agent, Bond):
#                raise Exception(str(state.getCurrentPlayer()) + ' failed to return a move in time.')
            
            successors = state.getSuccessors()
            if action not in successors.keys():
                raise Exception(str(state.getCurrentPlayer()) + ' made an illegal move.')
            
            state = successors[action]
            
#            print action
#            print state
        print 'number of turns left', state.turns_left
        return state.getWinner()

if __name__ == '__main__':
    agents = {}
    agents[BLACK] = Bond()
    agents[WHITE] = BondNoFramePenalty()
    
    print "start test"
    result_file  = open("C:\Users\Avi\Documents\PythonProjects\AI2_results_Bond_vs_NoPenaltyBond2.txt","w")
    result_file.write("Bond vs Bond with no frame penalty \n")
    
    for size in xrange(5, 8):
        for limit in xrange(20, 50, 5):
            for time in xrange(1, 6):
                
                state = LinesOfActionState(size, limit)
                winner = GameRunner(state, agents, 5*time, 1).run()
                params = "size:", size, "turns limit:", limit, "turn time:", time 
                output = "Bond root cache hit number = " , ModifiedAlphaBetaSearch.root_cache_hit, "root cache hit rate = ", float(ModifiedAlphaBetaSearch.root_cache_hit)/(ModifiedAlphaBetaSearch.root_cache_hit + ModifiedAlphaBetaSearch.root_cache_miss), "leaves cache hit number = ", ModifiedAlphaBetaSearch.leaves_cache_hit, "leaves cache hit rate = ", float(ModifiedAlphaBetaSearch.leaves_cache_hit)/(ModifiedAlphaBetaSearch.leaves_cache_hit + ModifiedAlphaBetaSearch.leaves_cache_miss)
                output2 = "BondNoPenalty root cache hit number = " , ModifiedAlphaBetaSearchNoPenalty.root_cache_hit, "root cache hit rate = ", float(ModifiedAlphaBetaSearchNoPenalty.root_cache_hit)/(ModifiedAlphaBetaSearchNoPenalty.root_cache_hit + ModifiedAlphaBetaSearchNoPenalty.root_cache_miss), "leaves cache hit number = ", ModifiedAlphaBetaSearchNoPenalty.leaves_cache_hit, "leaves cache hit rate = ", float(ModifiedAlphaBetaSearchNoPenalty.leaves_cache_hit)/(ModifiedAlphaBetaSearchNoPenalty.leaves_cache_hit + ModifiedAlphaBetaSearchNoPenalty.leaves_cache_miss)
                output3 = 'Winner:', winner
                result_file.writelines(str(params) + '\n')  
                result_file.writelines(str(output) + '\n')
                result_file.writelines(str(output2) + '\n')
                result_file.writelines(str(output3) + '\n')
                result_file.flush()
    
    result_file.close()
    print "end test"            